﻿using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business.CXYXTHNR;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Reports.CXYXTHNRA.Dtos;
using NP.BPMReportPlatform.Reports.POCAP;
using NP.BPMReportPlatform.Utils;
using NP.Enterprise.Utils.Http;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.Utilities;
using Serilog;
using Microsoft.Extensions.Configuration;
using NP.BPMReportPlatform.Reports.DailyCloseBook.Dtos;
using NP.BPMReportPlatform.Entities.BPM_Business.DailyCloseBook;
using Renci.SshNet.Common;
using NP.BPMReportPlatform.Entities.BPM_Engine;

namespace NP.BPMReportPlatform.Reports.DailyCloseBook
{
    public class DailyCloseBookService : BPMReportPlatformAppService, IDailyCloseBookService
    {
        private readonly SqlSugarClient _db;
        private readonly SqlSugarClient _dbPlatform;
        private readonly SqlSugarClient _dbEngine;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly ILogger _logger;
        private readonly IConfiguration _configuration;
        private readonly INPRestHttpHelper _nPRestHttp;
        public DailyCloseBookService(ISqlSugarAppService sqlSugarAppService, IBPMUtilsAppService bPMUtilsApp
            , IBPMPlatformAppService iBPMPlatformApp, ILogger logger, IConfiguration configuration
            , INPRestHttpHelper nPRestHttp)
        {
            _db = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _dbEngine = sqlSugarAppService.GetEngineInstance();
            _bPMUtilsApp = bPMUtilsApp;
            _iBPMPlatformApp = iBPMPlatformApp;
            _logger = logger;
            _configuration = configuration;
            _nPRestHttp = nPRestHttp;
        }

        public async Task<PagedResultDto<GetDailyCloseBookOutput>> GetAllAsync(DailyCloseBookInput input)
        {
            RefAsync<int> totalCount = 0;

            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);

            listViewDto.ForEach(x =>
            {
                x.Url = _bPMUtilsApp.GetProcessUrl(x.InstanceNumber, userId);
                if (x.Status == 2)
                {
                    x.StatusDesc = "审批完成";
                }
                else if (x.LatestActivityName == "一级审批")
                {
                    x.StatusDesc = "一级审批中";
                }
                else if (x.LatestActivityName == "二级审批")
                {
                    x.StatusDesc = "二级审批中";
                }
            });

            //返回结果
            return new PagedResultDto<GetDailyCloseBookOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetDailyCloseBookOutput>> ExportAsync(DailyCloseBookInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();

            listViewDto.ForEach(x =>
            {
                if (x.Status == 2)
                {
                    x.StatusDesc = "审批完成";
                }
                else if (x.LatestActivityName == "一级审批")
                {
                    x.StatusDesc = "一级审批中";
                }
                else if (x.LatestActivityName == "二级审批")
                {
                    x.StatusDesc = "二级审批中";
                }
            });

            return listViewDto;
        }

        private ISugarQueryable<GetDailyCloseBookOutput> GetQueryable(DailyCloseBookInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>().Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }

            var query = _db.Queryable<DailyCloseBookHeader, DailyCloseBookDetail>(
                    (x, d) => x.InstanceNumber == d.InstanceNumber)
                .InnerJoin<Instances>((x, d, i) => i.Number == x.InstanceNumber).AS<Instances>("BPM_Engine.Instances")
                .InnerJoin<InstanceStates>((x, d, i, s) => i.InstanceId == s.InstanceId).AS<InstanceStates>("BPM_Engine.InstanceStates");
            var listQueryable = query
                .Where((x, d, i, s) => i.BTID == "DailyCloseBook")
                .WhereIF(!input.IsQueryAll, (x, d, i, s) => x.AddUserId.Equals(currentUserId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, d, i, s) => x.InstanceNumber == input.InstanceNumber)
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, d, i, s) => x.AddUserName.Contains(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null,
                    (x, d, i, s) => x.AddTime >= input.StartCreationTime && x.AddTime <= input.EndCreationTime)
                .WhereIF(input.IsSyncSuccess.HasValue, (x, d, i, s) => x.IsSyncSuccess == input.IsSyncSuccess)
                .WhereIF(!string.IsNullOrWhiteSpace(input.PWSCode), (x, d, i, s) => d.PWSCode.Contains(input.PWSCode))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Factory), (x, d, i, s) => d.Factory.Contains(input.Factory) || d.FactoryDesc.Contains(input.Factory))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Material), (x, d, i, s) => d.MaterialCode.Contains(input.Material) || d.MaterialDesc.Contains(input.Material))
                .Select((x, d, i, s) => new GetDailyCloseBookOutput()
                {
                    InstanceNumber = d.InstanceNumber,
                    AddTimeStr = x.AddTime.ToString(DateFormatHelper.DateTimeFormat),
                    SyncTime = d.SyncTime,
                    SyncTimeStr = d.SyncTime != null ? d.SyncTime.Value.ToString(DateFormatHelper.DateTimeFormat) : "",
                    PWSCode = d.PWSCode,
                    Factory = d.Factory,
                    FactoryDesc = d.FactoryDesc,
                    ApplyReason = d.ApplyReason,
                    MaterialCode = d.MaterialCode,
                    MaterialDesc = d.MaterialDesc,
                    Quantity = d.Quantity,
                    Unit = d.Unit,
                    MRP = d.MRP,
                    AddUserName = x.AddUserName,
                    Approver1UserName = x.Approver1UserName,
                    Approver2UserName = x.Approver2UserName,
                    SyncResult = SqlFunc.IIF(d.IsSyncSuccess, "修改成功", d.SyncResult),
                    AddTime = x.AddTime,
                    Status = s.Status,
                    LatestActivityName = s.LatestActivityName,
                }).MergeTable().Distinct().OrderBy(ins => ins.AddTime, OrderByType.Desc);
            return listQueryable;
        }
    }
}
